/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.mes.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.mes.base.utils.StringUtils;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.mes.base.entity.PrdBom;
import org.springblade.modules.mes.base.entity.PrdInfo;
import org.springblade.modules.mes.base.mapper.PrdBomMapper;
import org.springblade.modules.mes.base.mapper.PrdInfoMapper;
import org.springblade.modules.mes.base.service.IPrdInfoService;
import org.springblade.modules.mes.base.vo.PrdInfoVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 产品信息 服务实现类
 *
 * @author BladeX
 * @since 2020-09-08
 */
@Service
public class PrdInfoServiceImpl extends BaseServiceImpl<PrdInfoMapper, PrdInfo> implements IPrdInfoService {

	@Resource
	private PrdBomMapper prdBomMapper;


	@Override
	public List<PrdInfoVO> getPrdInfoVOList(PrdInfoVO prdInfoVO) {
		return baseMapper.getPrdInfoVOList(prdInfoVO);
	}

	@Override
	public List<PrdInfoVO> listByName(String prdName,String productType) {
		return baseMapper.listByName(prdName,productType, AuthUtil.getTenantId());
	}

	@Override
	public List<PrdInfoVO> listByNameQua(String prdName, String productType) {
		return baseMapper.listByNameQua(prdName,productType, AuthUtil.getTenantId());
	}

    @Override
    public PrdInfoVO findByMaterialNo(String materialNo) {
        return baseMapper.findByMaterialNo(materialNo);
    }

    @Override
    public R updateProductUnitPrice(PrdInfoVO prdInfoVO) {
        return R.status(baseMapper.updateProductUnitPrice(prdInfoVO));
    }

    @Override
    public void exportWaste(HttpServletRequest request, HttpServletResponse response, PrdInfoVO prdInfo, String ids) {
        Map<String,Object>map = new HashMap<>();
        List<PrdInfoVO> prdInfoVOList;
        if(StringUtils.isNotBlank(ids)){
            prdInfoVOList=baseMapper.selectByIds(Func.toLongList(ids));
        }else{
            prdInfoVOList=baseMapper.selectPrdInfoPage(null, prdInfo);
        }
        map.put("list",prdInfoVOList);
//        ExcelUtil.export(request,response,map,"废品返修金额设置","废品返修金额设置",false);
    }

    @Override
    public R uploadWaste(Map<String, Object> map) {
        ArrayList<String[]> data = (ArrayList<String[]>) map.get("data");
        List<PrdInfo> prdInfoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(data)){
            Iterator<String[]> iterator = data.iterator();
            while (iterator.hasNext()){
                String[] obj = iterator.next();
                if(StringUtils.isEmpty(obj[0])&& StringUtils.isEmpty(obj[5])&& StringUtils.isEmpty(obj[6])){
                    continue;
                }
                if (StringUtils.isEmpty(obj[0])){
                    throw new ServiceException("产品编码不能为空");
                }
                //校验编码是否存在
                long count=baseMapper.selectCount(new LambdaQueryWrapper<PrdInfo>().eq(PrdInfo::getMaterialNo,obj[0]));
                if(count==0){
                    throw new ServiceException("产品编码“"+obj[0]+"”不存在");
                }
                PrdInfo prdInfo = new PrdInfo();
                prdInfo.setMaterialNo(obj[0]);
                prdInfo.setProductUnitPrice(obj[5]);
                if(obj[6].length()>30){
                    throw new ServiceException("产品编码“"+obj[0]+"”备注应不超过30位");
                }
                prdInfo.setProductRemark(obj[6]);
                prdInfoList.add(prdInfo);
            }
        } else {
            throw new ServiceException("导入的数据不能为空！");
        }
        return R.status(baseMapper.updateByNoList(prdInfoList));
    }

    @Override
	public IPage<PrdInfoVO> selectPrdInfoPage(IPage<PrdInfoVO> page, PrdInfoVO prdInfo) {
		return page.setRecords(baseMapper.selectPrdInfoPage(page, prdInfo));
	}

	@Override
	public IPage<PrdInfoVO> selectTopPrdInfoPage(IPage<PrdInfoVO> page, PrdInfoVO prdInfo) {
		return page.setRecords(baseMapper.selectTopPrdInfoPage(page, prdInfo));
	}

//	@Override
//	public int selectCountByDrawingNo(PrdInfo prdInfo) {
//		return prdInfoMapper.selectCountByDrawingNo(prdInfo);
//	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deletePrdAndBom(List<Long> ids, List<String> productDrawingNos) {
		if(ids == null || ids.size() == 0 /*|| productDrawingNos == null || productDrawingNos.size() == 0*/){
			return false;
		}
//		//1.删除产品表
//		super.deleteLogic(ids);
		//2.删除项目产品表
//		List<Long> prjPrdIds = projectPrdInfoService.getIdsByPrdDrawingNos(productDrawingNos);//包含要删除的这些产品的项目产品id
//		if(prjPrdIds!=null && prjPrdIds.size()>0){
//		}
//		//3.删除BOM表
		List<PrdInfo> prdInfoList = baseMapper.selectBatchIds(ids);
		List<String> productDrawingNoList = prdInfoList.stream().map(PrdInfo::getMaterialNo).collect(Collectors.toList());
		long count = prdBomMapper.selectCount(new LambdaQueryWrapper<PrdBom>().in(PrdBom::getMaterialNo,productDrawingNoList).or().in(PrdBom::getDirectLeaderNo,productDrawingNoList));
		if (count>0) {
			prdBomMapper.deleteBomBySupAndMaterialNo(productDrawingNoList, productDrawingNoList);
		}
//		List<String> bomNos = prdBomService.getBoNosByPrdDrawingNos(productDrawingNos);//根据产品图号查询BOM序号
//		if(bomNos!=null && bomNos.size()>0){
//			List<Long> bomIds = prdBomService.getBomIdsByBomNos(bomNos);//根据BOM序号查询当前及下级id
//			boolean flag = prdBomService.deleteLogic(bomIds);
//
//			/**异步向生产推送BOM信息-删除 start**/
////			if(flag){
////				ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
////				PrdBomSyncThread thread = new PrdBomSyncThread(3,null, bomIds);
////				cachedThreadPool.execute(thread);
////			}
//			/**异步向生产推送BOM信息-删除 end**/
//		}
		//1.删除产品表
		return this.deleteLogic(ids);
	}

//	@Override
//	public PrdInfoVO getDetailWithBom(PrdInfo prdInfo) {
//		//根据产品图号查询产品信息
//		PrdInfo detail = this.getOne(new QueryWrapper<PrdInfo>().eq("product_drawing_no", prdInfo.getInnerDrawingNo()));
//		if(detail == null ){
//			return null;
//		}
//
//		PrdInfoVO prdInfoVO = PrdInfoWrapper.build().entityVO(detail);
//		if("2".equals(detail.getQuotaFlag())){//定额标识为"2"-定额
//			//查询直接上级图号为该产品的图号，并且flag为"2"-材料的信息
//			List<PrdBom2> prdBom2List = prdBomService.list(new QueryWrapper<PrdBom2>()
//					.eq("direct_leader_no", detail.getInnerDrawingNo())
//					.eq("flag","2"));
//			if(prdBom2List ==null || prdBom2List.size()==0){
//				throw new ValidationException("该定额产品下没有材料信息，请查验原因！");
//			}
//			//一个产品可能有多个上级，但组成该产品的材料信息相同，所以材料信息取第一条即可
//			PrdBom2 prdBom2 = prdBom2List.get(0);
//			if(prdBom2 != null){
//				MaterialInfo materialInfo = materialInfoService.getOne(new QueryWrapper<MaterialInfo>().eq("material_grade", prdBom2.getProductDrawingNo()));
//				prdInfoVO.setMaterialName(materialInfo.getMaterialName());//材料名称
//				prdInfoVO.setMaterialGrade(prdBom2.getProductDrawingNo());//材料牌号
//				prdInfoVO.setMaterialTypeId(prdBom2.getMaterialTypeId());//材料类型id
//				prdInfoVO.setMaterialQuota(prdBom2.getQuota());//材料定额
//				prdInfoVO.setLossRate(prdBom2.getLossRate());//损耗率
//			}
//		}
//
//
//		return prdInfoVO;
//	}
//
//	@Override
//	public List<PrdInfoVO> listWithType() {
//		return prdInfoMapper.listWithType();
//	}

	@Override
	public List<PrdInfo> listWithDeleted(Date startTime, Date endTime) {
		return baseMapper.listWithDeleted(startTime, endTime, AuthUtil.getTenantId());
	}

//	@Override
//	public List<PrdInfoVO> selectTopPrdInfoNotPage(PrdInfoVO prdInfo) {
//		return prdInfoMapper.selectTopPrdInfoPage(null, prdInfo);
//	}

//	@Override
//	@Transactional(rollbackFor = Exception.class)
//	public boolean savePrdAndBom(PrdInfoVO prdInfoVO) {
//		//新增产品主数据
//		prdInfoVO.setProductNo(this.createProductNo());
//		super.save(prdInfoVO);
//		//判断定额标识是否为【定额】或【BOM】(字典：1-BOM，2-定额)
//		if("1".equals(prdInfoVO.getQuotaFlag()) || "2".equals(prdInfoVO.getQuotaFlag())){
//			//判断要添加的产品是否为顶级产品
//			if(StringUtils.isBlank(prdInfoVO.getDirectLeaders())){//没有直接上级，为顶级产品，直接新增BOM表
//				PrdBom prdBom = new PrdBom();
//				//查询BOM表顶级产品的数量，根据这个数量设置BOM序号
//				prdBom.setDirectLeaderNo(null);
//				int count = prdBomService.selectCountByDirectLeader(prdBom);
//				prdBom.setBomNo(String.valueOf(count+1));//设置BOM序号
//				prdBom.setTopDrawingNo(prdInfoVO.getProductDrawingNo());//最顶层产品图号
//				prdBom.setProductNo(prdInfoVO.getProductNo());//产品编码
//				prdBom.setProductDrawingNo(prdInfoVO.getProductDrawingNo());//产品图号
//				prdBom.setFlag("1");//设置标识为：1-产品
//				prdBomService.save(prdBom);
//
//				//如果定额标识为"定额"，BOM再增加一条材料的数据
//				if("2".equals(prdInfoVO.getQuotaFlag())){
//					//判断材料是不是原材料
//					MaterialType materialType = materialTypeService.getOne(new QueryWrapper<MaterialType>().eq("id",prdInfoVO.getMaterialTypeId()));
//					if(!"1".equals(materialType.getRawMaterialFlag())){
//						throw new ValidationException("材料不是原材料！");
//					}
//					PrdBom prdMatBom = new PrdBom();
//					prdMatBom.setBomNo(prdBom.getBomNo()+".1");//设置BOM序号
//					prdMatBom.setProductDrawingNo(prdInfoVO.getMaterialGrade());//材料牌号
//					prdMatBom.setDirectLeaderNo(prdInfoVO.getProductDrawingNo());//直接上级（即上面的产品的图号）
//					prdMatBom.setMaterialTypeId(prdInfoVO.getMaterialTypeId());//材料类型id
//					prdMatBom.setTopDrawingNo(prdBom.getTopDrawingNo());//最顶层产品图号
//					prdMatBom.setQuota(prdInfoVO.getMaterialQuota());//每套用量（定额）—— 材料定额
//					prdMatBom.setLossRate(prdInfoVO.getLossRate());//损耗率
//					prdMatBom.setFlag("2");//设置标识为：2-材料
//					prdBomService.save(prdMatBom);
//				}
//			}else{//有直接上级，不是顶级产品
//				List<String> directLeaderList = Func.toStrList(prdInfoVO.getDirectLeaders());//直接上级产品图号列表
//				List<PrdInfo> prdInfoList = super.list(new QueryWrapper<PrdInfo>().in("product_drawing_no", directLeaderList));
//				List<String> quotaFlags = prdInfoList.stream().map(item -> item.getQuotaFlag()).collect(Collectors.toList());
//				//判断直接上级的定额标识，如果是"定额"或"空"，则不能作为上级产品
//				if(quotaFlags.contains("2") || quotaFlags.contains("3")){
//					throw new ValidationException("上级产品的BOM标识只能为[BOM]");
//				}
//				List<PrdBom> dbLeaderBomList = prdBomService.list(new QueryWrapper<PrdBom>().in("product_drawing_no", directLeaderList));//上级产品的bom列表
//				for(PrdBom leaderBom : dbLeaderBomList){
//					PrdBom prdBom = new PrdBom();
//					String topDrawingNo = leaderBom.getTopDrawingNo();
//					String leaderBomNo = leaderBom.getBomNo();
//					int count = prdBomService.countSameUpper(leaderBom.getProductDrawingNo(),leaderBom.getTopDrawingNo());
//					prdBom.setBomNo(leaderBomNo+"."+(count+1));//设置BOM序号
//					prdBom.setTopDrawingNo(topDrawingNo);//最顶层产品图号
//					prdBom.setDirectLeaderNo(leaderBom.getProductDrawingNo());
//					prdBom.setProductNo(prdInfoVO.getProductNo());//产品编码
//					prdBom.setProductDrawingNo(prdInfoVO.getProductDrawingNo());//产品图号
//					prdBom.setFlag("1");//设置标识为：1-产品
//					prdBomService.save(prdBom);
//
//					//如果定额标识为"定额"，BOM再增加一条材料的数据
//					if("2".equals(prdInfoVO.getQuotaFlag())){
//						//判断材料是不是原材料
//						MaterialType materialType = materialTypeService.getOne(new QueryWrapper<MaterialType>().eq("id",prdInfoVO.getMaterialTypeId()));
//						if(!"1".equals(materialType.getRawMaterialFlag())){
//							throw new ValidationException("材料不是原材料！");
//						}
//						PrdBom prdMatBom = new PrdBom();
//						prdMatBom.setBomNo(prdBom.getBomNo()+".1");//设置BOM序号
//						prdMatBom.setProductDrawingNo(prdInfoVO.getMaterialGrade());//材料牌号
//						prdMatBom.setDirectLeaderNo(prdInfoVO.getProductDrawingNo());//直接上级（即上面的产品的图号）
//						prdMatBom.setMaterialTypeId(prdInfoVO.getMaterialTypeId());//材料类型id
//						prdMatBom.setTopDrawingNo(prdBom.getTopDrawingNo());//最顶层产品图号
//						prdMatBom.setQuota(prdInfoVO.getMaterialQuota());//每套用量（定额）—— 材料定额
//						prdMatBom.setLossRate(prdInfoVO.getLossRate());//损耗率
//						prdMatBom.setFlag("2");//设置标识为：2-材料
//						prdBomService.save(prdMatBom);
//					}
//				}
//			}
//		}
//
//
//		return true;
//	}

//	@Override
//	@Transactional(rollbackFor = Exception.class)
//	public boolean updatePrdAndBom(PrdInfoVO prdInfoVO) {
//		//修改产品主数据表
//		super.updateById(prdInfoVO);
//		//如果定额标识为"2-定额"时，修改bom信息的【材料定额】、【损耗率】
//		if("2".equals(prdInfoVO.getQuotaFlag())){
//			List<PrdBom> bomList = prdBomService.list(new QueryWrapper<PrdBom>().eq("product_drawing_no", prdInfoVO.getMaterialGrade()));
//			bomList.forEach(item -> {
//				item.setQuota(prdInfoVO.getMaterialQuota());
//				item.setLossRate(prdInfoVO.getLossRate());
//			});
//			//批量更新bom表
//			prdBomService.updateBatchById(bomList);
//		}
//		return true;
//	}


	/**
	 * 生成产品编码
	 * 10位：CP+数字，中间位数不足补0
	 * @return
	 */
	@Override
	public String createProductNo(PrdInfoVO prdInfoVO){
		String prefix=new StringBuffer().append(prdInfoVO.getMaterialType()).append(prdInfoVO.getMaterialGroupNo()).toString();
		List<PrdInfoVO> list = baseMapper.listOfPrdNo(prefix, AuthUtil.getTenantId());//查询编码,按编码倒序
		String newPrdNo = null;
		if(list!=null && list.size()>0){
			String maxPrdNo = list.get(0).getMaterialNo().split("-")[0];
//			int suf = 1;
//			if (Integer.parseInt(maxPrdNo.substring(prefix.length()+3))>=10){
//				suf = 2;
//			}
			Long newLong = Long.parseLong(maxPrdNo.substring(prefix.length(),maxPrdNo.length()-2)) + 1;
			newPrdNo = prefix + String.format("%0"+3+"d", newLong);
		}else{
			newPrdNo = prefix+"001";
		}

		return newPrdNo+ StringUtils.trim(prdInfoVO.getVersion());

//		return StringUtils.trim(prdInfoVO.getInnerDrawingNo()) + "-" +  StringUtils.trim(prdInfoVO.getVersion());
	}

	@Override
	public int countByMaterialNo(PrdInfoVO prdInfoVO) {
		return baseMapper.countByMaterialNo(prdInfoVO);
	}

	@Override
	public List<PrdInfoVO> materialByTypeAndGroup(PrdInfoVO prdInfo) {
		return baseMapper.materialByTypeAndGroup(prdInfo);
	}

	/**
	 * 验证产品名称+规格+型号是否重复
	 * @param id
	 * @param materialName
	 * @param specifications
	 * @param model
	 * @return
	 */
    @Override
    public int countByNameSpecModel(Long id, String materialName, String specifications, String model) {
        return baseMapper.countByNameSpecModel(id,materialName,specifications,model, AuthUtil.getTenantId());
    }

	@Override
	public R uploadPrdInfo(Map<String, Object> map) {
		ArrayList<String[]> data = (ArrayList<String[]>) map.get("data");
		List<PrdInfo> prdInfoList = new ArrayList<>();
		if (CollectionUtil.isNotEmpty(data)){
			List<String> materialNos = baseMapper.listByName(null,null, AuthUtil.getTenantId()).stream().map(item->item.getMaterialNo()).collect(Collectors.toList());
			List<String> materialNames = baseMapper.getName();
			Iterator<String[]> iterator = data.iterator();
			while (iterator.hasNext()){
				String[] obj = iterator.next();
				if (StringUtils.isEmpty(obj[0])){
					throw new ServiceException("产品编码不能为空");
				}
				if (StringUtils.isEmpty(obj[1])){
					throw new ServiceException("产品名称不能为空");
				}
				if (StringUtils.isEmpty(obj[2])){
					throw new ServiceException("产品图号不能为空");
				}
				if (StringUtils.isEmpty(obj[3])){
					throw new ServiceException("产品类型不能为空");
				}
				if (StringUtils.isEmpty(obj[4])){
					throw new ServiceException("物料组编码不能为空");
				}
				if (StringUtils.isEmpty(obj[7])){
					throw new ServiceException("计量单位不能为空");
				}
				if (materialNos.contains(obj[0])){
					throw new ServiceException("产品编码："+obj[0]+"  已经存在");
				}
				if (materialNames.contains(obj[1]+","+obj[5]+","+obj[6])){
					throw new ServiceException("产品名称："+obj[1]+"  已经存在");
				}
				PrdInfo prdInfo = new PrdInfo();
				prdInfo.setMaterialFlag("P");
				if (StringUtils.isNotEmpty(obj[10])) {
					prdInfo.setQuotaFlag(obj[10]);
				}
				prdInfo.setVersion("01");
				prdInfo.setProductStatus("1");
				prdInfo.setMaterialNo(obj[0]);
				prdInfo.setFormulaNo(obj[0].substring(obj[0].length()-3));
				prdInfo.setMaterialName(obj[1]);
				prdInfo.setInnerDrawingNo(obj[2]);
				prdInfo.setMaterialType(obj[3]);
				prdInfo.setMaterialGroupNo(obj[4]);
				prdInfo.setSpecifications(obj[5]);
				prdInfo.setModel(obj[6]);
				prdInfo.setOriginalDrawingNo(obj[9]);
				materialNos.add(obj[0]);
				materialNames.add(obj[1]+","+obj[5]+","+obj[6]);
				prdInfoList.add(prdInfo);
			}
		} else {
			throw new ServiceException("导入的数据不能为空！");
		}
		return R.status(super.saveBatch(prdInfoList));
	}

	@Override
	public void exportPrdInfo(HttpServletRequest request, HttpServletResponse response, PrdInfoVO prdInfo, String ids) {
    	if (StringUtils.isNotEmpty(ids)) {
    		PrdInfoVO vo = new PrdInfoVO();
    		vo.setIds(Func.toLongList(ids));
			List<PrdInfoVO> prdInfoList = baseMapper.selectPrdInfoPage(null,vo);
//			List<PrdInfo> prdInfoList = baseMapper.selectBatchIds(Func.toLongList(ids));
//			if (prdInfoList!=null){
//				List<UnitEntity> unitEntityList = unitMapper.selectList(new QueryWrapper<UnitEntity>());
//				Map<String,String> unitMap = new HashMap<>();
//				if (CollectionUtil.isNotEmpty(unitEntityList)){
//					for (UnitEntity unit:unitEntityList){
//						unitMap.put(unit.getCode(),unit.getName());
//					}
//				}
//				List<PrdInfoVO> voList = PrdInfoWrapper.build().listVO(prdInfoList);
//				voList.forEach(item->{
//					item.setUnitName(unitMap.get(item.getUnit()));
//				});
			Map<String,Object>map = new HashMap<>();
			map.put("list",prdInfoList);
//			ExcelUtil.export(request,response,map,"产品主数据导出模板","产品主数据信息",false);
//			}
		} else {
    		prdInfo.setMaterialFlag("P");
    		List<PrdInfoVO> prdInfoList = baseMapper.selectPrdInfoPage(null,prdInfo);
			if (prdInfoList!=null){
				Map<String,Object>map = new HashMap<>();
				map.put("list",prdInfoList);
//				ExcelUtil.export(request,response,map,"产品主数据导出模板","产品主数据信息",false);
			}
		}
	}


}
